package com.jasic.comnt.protocol.bean;

import com.jasic.common.GlobalConstant;
import com.jasic.common.exception.HandleException;
import com.jasic.comnt.protocol.MessageCommon;
import com.jasic.util.ByteUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * User: Jasic
 * Date: 12-12-25
 *
 * 响应实体
 */
public class PostionResp extends BaseResponse {

    private static Logger logger = LoggerFactory.getLogger(PostionResp.class);

    /**
     * 经纬度倍数系数
     */
    private static final double COEF = 100000;

    /**
     * Client side used
     *
     * @param data
     */
    public PostionResp(byte[] data) throws HandleException {
        super(data);
    }

    /**
     * Server side used
     *
     * @param positionResult
     * @param target_id
     * @param target_type
     * @param alarmFlat
     * @param status
     * @param latitude
     * @param longitude
     * @param high
     * @param speed
     * @param direction
     */
    public PostionResp(int positionResult, String target_id, int target_type, int alarmFlat, int status, double latitude, double longitude, int high, int speed, int direction) {
        super(new MessageCommon(GlobalConstant.CMD_POSTIONRESP, GlobalConstant.POSTIONRESP_LENGTH));
        this.positionResult = positionResult;
        this.target_id = target_id;
        this.target_type = target_type;
        this.alarmFlat = alarmFlat;
        this.status = status;
        this.latitude = latitude;
        this.longitude = longitude;
        this.high = high;
        this.speed = speed;
        this.direction = direction;
        this.bcdTime = new SimpleDateFormat("yyMMDDhhmmss").format(new Date());

        super.initCheckNum();
    }

    // result
    private int positionResult;

    // number id
    private String target_id;

    // type
    private int target_type;

    // 报警标志0-3
    private int alarmFlat;

    // 状态 4-7
    private int status;

    // 纬度 8-11
    private double latitude;

    // 经度 12-15
    private double longitude;

    // 高度
    private int high;

    // 速度
    private int speed;

    // 方向
    private int direction;

    // 时间
    private String bcdTime;

    @Override
    protected byte[] getMsgByte() {
        byte[] msgByte = new byte[GlobalConstant.POSTIONRESP_MSG_LENGTH];

        int pos = 0;
        int len = 0;
        byte[] bytes = null;

        bytes = ByteUtil.stringToBCD(this.target_id);
        len = 8;
        if (bytes.length > len) {
            throw new RuntimeException("alarmFlatLen: larger than " + len);
        }
        pos += len;
        System.arraycopy(bytes, 0, msgByte, pos - bytes.length, bytes.length);

        bytes = new byte[]{(byte) this.target_type};
//        bytes = ByteUtil.uintToBytes(this.target_type);
        len = 1;
        if (bytes.length > len) {
            throw new RuntimeException("alarmFlatLen: larger than " + len);
        }
        pos += len;
        System.arraycopy(bytes, 0, msgByte, pos - bytes.length, bytes.length);

        bytes = ByteUtil.uintToBytes(this.alarmFlat);
        len = 4;
        if (bytes.length > len) {
            throw new RuntimeException("alarmFlatLen: larger than " + len);
        }
        pos += len;
        System.arraycopy(bytes, 0, msgByte, pos - bytes.length, bytes.length);

        bytes = ByteUtil.uintToBytes(this.status);
        len = 4;
        if (bytes.length > len) {
            throw new RuntimeException("status len: larger than " + len);
        }
        pos += len;
        System.arraycopy(bytes, 0, msgByte, pos - bytes.length, bytes.length);

        bytes = ByteUtil.uintToBytes((int) ((this.latitude) * COEF));
        len = 4;
        if (bytes.length > len) {
            throw new RuntimeException("latitude len: larger than " + len);
        }
        pos += len;
        System.arraycopy(bytes, 0, msgByte, pos - bytes.length, bytes.length);

        bytes = ByteUtil.uintToBytes((int) (this.longitude * COEF));
        len = 4;
        if (bytes.length > len) {
            throw new RuntimeException("longitude len: larger than " + len);
        }
        pos += len;
        System.arraycopy(bytes, 0, msgByte, pos - bytes.length, bytes.length);

        len = 2;
        bytes = new byte[2];
        byte[] temp = ByteUtil.ushortToBytes(this.high);//取最高两位
        System.arraycopy(temp, 0, bytes, 0, bytes.length);
        temp = null;
        if (bytes.length > len) {
            throw new RuntimeException("high len: larger than " + len);
        }
        pos += len;
        System.arraycopy(bytes, 0, msgByte, pos - bytes.length, bytes.length);

        len = 2;
        bytes = new byte[2];
        temp = ByteUtil.ushortToBytes(this.speed);//取最高两位
        System.arraycopy(temp, 0, bytes, 0, bytes.length);
        temp = null;
        if (bytes.length > len) {
            throw new RuntimeException("speed len: larger than " + len);
        }
        pos += len;
        System.arraycopy(bytes, 0, msgByte, pos - bytes.length, bytes.length);

        len = 2;
        bytes = new byte[2];
        temp = ByteUtil.ushortToBytes(this.direction);//取最高两位
        System.arraycopy(temp, 0, bytes, 0, bytes.length);
        temp = null;
        if (bytes.length > len) {
            throw new RuntimeException("direction len: larger than " + len);
        }
        pos += len;
        System.arraycopy(bytes, 0, msgByte, pos - bytes.length, bytes.length);

        bytes = ByteUtil.stringToBCD(this.bcdTime);
        len = 6;
        if (bytes.length > len) {
            throw new RuntimeException("bcdTime len: larger than " + len);
        }
        pos += len;
        System.arraycopy(bytes, 0, msgByte, pos - bytes.length, bytes.length);

        return msgByte;
    }

    @Override
    protected void setValues() throws HandleException {

        byte[] msgByte = super.msgByte;

        int actualLength = GlobalConstant.POSTIONRESP_LENGTH - MessageCommon.MSG_COMMON_LENGTH;
        if (msgByte.length != actualLength) {
            throw new HandleException("PostionResp's length is " + msgByte.length + ", but it must be " + actualLength);
        }
        byte[] target_id_BCD = new byte[8];
        System.arraycopy(msgByte, 0, target_id_BCD, 0, target_id_BCD.length);
        this.target_id = ByteUtil.bcdToString(target_id_BCD);

        logger.info("PostionResp target_id:" + target_id);

        // 指针位置
        int pos = target_id_BCD.length;
        target_id_BCD = null;
        int len = 0;

        len = 1;
        this.target_type = msgByte[pos];
        logger.info("target_type: " + target_type);
        pos += len;

        len = 4;
        this.alarmFlat = ByteUtil.bytesToUINT(msgByte, pos);
        logger.info("alarmFlat: " + alarmFlat);
        pos += len;

        len = 4;
        this.status = ByteUtil.bytesToUINT(msgByte, pos);
        logger.info("status: " + status);
        pos += len;

        len = 4;
        this.latitude = ((double) ByteUtil.bytesToUINT(msgByte, pos) / COEF);
        logger.info("latitude: " + latitude);
        pos += len;

        len = 4;
        this.longitude = ((double) ByteUtil.bytesToUINT(msgByte, pos) / COEF);
        logger.info("longitude: " + longitude);
        pos += len;

        len = 2;
        this.high = ByteUtil.bytesToUSHORT(msgByte, pos);
        logger.info("high: " + high);
        pos += len;

        len = 2;
        this.speed = ByteUtil.bytesToUSHORT(msgByte, pos);
        logger.info("speed: " + speed);
        pos += len;

        len = 2;
        this.direction = ByteUtil.bytesToUSHORT(msgByte, pos);
        logger.info("direction: " + direction);
        pos += len;

        len = 6;
        byte[] bcdTime_BCD = new byte[len];
        System.arraycopy(msgByte, pos, bcdTime_BCD, 0, len);
        this.bcdTime = ByteUtil.bcdToString(bcdTime_BCD);
        logger.info("bcdTime: " + bcdTime);
        bcdTime_BCD = null;
    }

    public int getTarget_type() {
        return target_type;
    }

    public String getTarget_id() {
        return target_id;
    }

    public int getStatus() {
        return status;
    }

    public double getLatitude() {
        return ((double) latitude / COEF);
    }

    public double getLongitude() {
        return ((longitude) / COEF);
    }

    public int getHigh() {
        return high;
    }

    public int getSpeed() {
        return speed;
    }

    public int getDirection() {
        return direction;
    }

    public String getBcdTime() {
        return bcdTime;
    }

    public int getAlarmFlat() {

        return alarmFlat;
    }

    public int getPositionResult() {
        return positionResult;
    }

    public void setPositionResult(int positionResult) {
        this.positionResult = positionResult;
    }

    public void setTarget_id(String target_id) {
        this.target_id = target_id;
    }

    public void setTarget_type(int target_type) {
        this.target_type = target_type;
    }
}
